package com.mycat.redis.util;

import com.mycat.redis.pool.JedisConnection;
import com.mycat.redis.pool.single.RedisSinglePool;
import redis.clients.jedis.Jedis;

import java.util.List;

/**
 * Redis字符串相关操作
 *
 * @author roger.
 * @email 190642964@qq.com
 * @create 2016-12-26
 */
public class RedisStringUtil {

    private static JedisConnection getInstance() {
        return RedisSinglePool.getInstance();
    }

    /**
     * 添加数据,如果key存在，则覆盖原有的数据
     *
     * @param key   键
     * @param value 值
     * @return OK
     */
    public static String set(String key, String value) {
        Jedis jedis = getInstance().getResource();
        String data = jedis.set(key, value);
        jedis.close();
        return data;
    }

    /**
     * 添加数据,如果key存在，则覆盖原有的数据
     *
     * @param key   键的byte[]
     * @param bytes 值的byte[]
     * @return OK
     */
    public static String set(byte[] key, byte[] bytes) {
        Jedis jedis = getInstance().getResource();
        String data = jedis.set(key, bytes);
        jedis.close();
        return data;
    }

    /**
     * 同时设置多个键值对,如果key存在，则覆盖原有的数据
     *
     * @param key_values 键值对
     * @return OK
     */
    public static String mset(String... key_values) {
        Jedis jedis = getInstance().getResource();
        String data = jedis.mset(key_values);
        jedis.close();
        return data;
    }

    /**
     * 同时设置多个键值对,如果key存在，则覆盖原有的数据
     *
     * @param key_values 键值对
     * @return OK
     */
    public static String mset(byte[]... key_values) {
        Jedis jedis = getInstance().getResource();
        String data = jedis.mset(key_values);
        jedis.close();
        return data;
    }

    /**
     * 同时设置多个键值对,如果key存在，则不执行设置操作(要么全部设置成功，要么全部设置失败)
     *
     * @param key_values 键值对
     * @return 所有key都设值成功-1，如果有1个key已存在则是失败-0
     */
    public static long msetnx(byte[]... key_values) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.msetnx(key_values);
        jedis.close();
        return data;
    }

    /**
     * 同时设置多个键值对,如果key存在，则不执行设置操作(要么全部设置成功，要么全部设置失败)
     *
     * @param key_values 键值对
     * @return 所有key都设值成功-1，如果有1个key已存在则是失败-0
     */
    public static long msetnx(String... key_values) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.msetnx(key_values);
        jedis.close();
        return data;
    }

    /**
     * 添加数据，当key不存在时可以设置value,当可以存在是不做任何动作
     *
     * @param key   键
     * @param value 值
     * @return 设置成功-1，设置失败-0
     */
    public static long setnx(String key, String value) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.setnx(key, value);
        jedis.close();
        return data;
    }

    /**
     * 添加数据，当key不存在时可以设置value,当可以存在是不做任何动作
     *
     * @param key   键的byte[]
     * @param value 值的byte[]
     * @return 设置成功-1，设置失败-0
     */
    public static long setnx(byte[] key, byte[] value) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.setnx(key, value);
        jedis.close();
        return data;
    }

    /**
     * 设置值的同时设置key的生存时间(如果key存在，则覆盖旧值)
     *
     * @param key     键
     * @param seconds 键的生存时间，单位：秒
     * @param value   值
     * @return 设置成功返回-OK，失败-错误
     */
    public static String setex(byte[] key, int seconds, byte[] value) {
        Jedis jedis = getInstance().getResource();
        String data = jedis.setex(key, seconds, value);
        jedis.close();
        return data;
    }

    /**
     * 设置值的同时设置key的生存时间(如果key存在，则覆盖旧值)
     *
     * @param key     键
     * @param seconds 键的生存时间，单位：秒
     * @param value   值
     * @return 设置成功返回-OK，失败-错误
     */
    public static String setex(String key, int seconds, String value) {
        Jedis jedis = getInstance().getResource();
        String data = jedis.setex(key, seconds, value);
        jedis.close();
        return data;
    }

    /**
     * 设置key的过期时间，如果key不存在不做任何操作
     *
     * @param key     键
     * @param seconds 过期时间，单位：秒
     * @return 设置成功-1，设置失败-0
     */
    public static long expire(String key, int seconds) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.expire(key, seconds);
        jedis.close();
        return data;
    }

    /**
     * 设置key的过期时间，如果key不存在不做任何操作
     *
     * @param key     键
     * @param seconds 过期时间，单位：秒
     * @return 设置成功-1，设置失败-0
     */
    public static long expire(byte[] key, int seconds) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.expire(key, seconds);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的数字值增1。如果不存在，会先把value初始化为0，在加1
     *
     * @param key 键
     * @return 执行incr命令后key的值
     */
    public static long incr(byte[] key) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.incr(key);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的数字值增1。如果不存在，会先把value初始化为0，在加1
     *
     * @param key 键
     * @return 执行incr命令后key的值
     */
    public static long incr(String key) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.incr(key);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的数字增加increment。如果不存在，会先把value初始化为0，在加increment
     *
     * @param key       键
     * @param increment 增量
     * @return 加上increment增量后的值
     */
    public static long incrBy(String key, long increment) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.incrBy(key, increment);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的数字增加increment。如果不存在，会先把value初始化为0，在加increment
     *
     * @param key       键
     * @param increment 增量
     * @return 加上increment增量后的值
     */
    public static long incrBy(byte[] key, long increment) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.incrBy(key, increment);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的浮点数字增加increment。如果不存在，会先把value初始化为0，在加increment
     *
     * @param key       键
     * @param increment 增量
     * @return 加上increment增量后的值
     */
    public static double incrByFloat(byte[] key, double increment) {
        Jedis jedis = getInstance().getResource();
        double data = jedis.incrByFloat(key, increment);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的浮点数字增加increment。如果不存在，会先把value初始化为0，在加increment
     *
     * @param key       键
     * @param increment 增量
     * @return 加上increment增量后的值
     */
    public static double incrByFloat(String key, double increment) {
        Jedis jedis = getInstance().getResource();
        double data = jedis.incrByFloat(key, increment);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的数字值减1。如果不存在，会先把value初始化为0，在减1
     *
     * @param key 键
     * @return 执行decr命令后key的值
     */
    public static long decr(byte[] key) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.decr(key);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的数字值减1。如果不存在，会先把value初始化为0，在减1
     *
     * @param key 键
     * @return 执行decr命令后key的值
     */
    public static long decr(String key) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.decr(key);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的数字减少decrement。如果不存在，会先把value初始化为0，在减decrement
     *
     * @param key       键
     * @param decrement 减少量
     * @return 减去decrement的值
     */
    public static long decrBy(String key, long decrement) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.decrBy(key, decrement);
        jedis.close();
        return data;
    }

    /**
     * 将key中存储的数字减少decrement。如果不存在，会先把value初始化为0，在减decrement
     *
     * @param key       键
     * @param decrement 减少量
     * @return 减去decrement的值
     */
    public static long decrBy(byte[] key, long decrement) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.decrBy(key, decrement);
        jedis.close();
        return data;
    }

    /**
     * 获取值
     *
     * @param key 键
     * @return 值
     */
    public static String get(String key) {
        Jedis jedis = getInstance().getResource();
        String data = jedis.get(key);
        jedis.close();
        return data;
    }

    /**
     * 获取值(byte[])
     *
     * @param key 键的byte[]
     * @return 值的byte[]
     */
    public static byte[] get(byte[] key) {
        Jedis jedis = getInstance().getResource();
        byte[] bytes = jedis.get(key);
        jedis.close();
        return bytes;
    }

    /**
     * 获取值多个键的值集合
     *
     * @param keys 多个键的byte[]
     * @return 多个键的值的byte[]集合
     */
    public static List<byte[]> mget(byte[]... keys) {
        Jedis jedis = getInstance().getResource();
        List<byte[]> data = jedis.mget(keys);
        jedis.close();
        return data;
    }

    /**
     * 获取值多个键的值集合
     *
     * @param keys 多个键
     * @return 多个键的值的byte[]集合
     */
    public static List<String> mget(String... keys) {
        Jedis jedis = getInstance().getResource();
        List<String> data = jedis.mget(keys);
        jedis.close();
        return data;
    }

    /**
     * 获取字符串中的子字符串，字符串的截取位置范围有startOffset和endOffset两个偏移量决定。
     * 负偏移量表示从字符串最后开始计算，-1表示最后一个字符，-1表示倒数第二个字符，以此类推.
     *
     * @param key         键
     * @param startOffset 开始偏移量，字符串从下标0开始
     * @param endOffset   结束偏移量，包含当前结束下标。超出范围的部分默认忽略
     * @return 截取后的字符串
     */
    public static String getrange(String key, int startOffset, int endOffset) {
        Jedis jedis = getInstance().getResource();
        String data = jedis.getrange(key, startOffset, endOffset);
        jedis.close();
        return data;
    }

    /**
     * 获取字符串中的子字符串，字符串的截取位置范围有startOffset和endOffset两个偏移量决定。
     * 负偏移量表示从字符串最后开始计算，-1表示最后一个字符，-1表示倒数第二个字符，以此类推
     *
     * @param key         键
     * @param startOffset 开始偏移量，字符串从下标0开始
     * @param endOffset   结束偏移量，包含当前结束下标。超出范围的部分默认忽略
     * @return 截取后的字符串
     */
    public static byte[] getrange(byte[] key, int startOffset, int endOffset) {
        Jedis jedis = getInstance().getResource();
        byte[] data = jedis.getrange(key, startOffset, endOffset);
        jedis.close();
        return data;
    }

    /**
     * 删除一个key
     *
     * @param key 键
     * @return 删除成功-1，失败-0
     */
    public static long del(String key) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.del(key);
        jedis.close();
        return data;
    }

    /**
     * 删除一个key
     *
     * @param key 键
     * @return 删除成功-1，失败-0
     */
    public static long del(byte[] key) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.del(key);
        jedis.close();
        return data;
    }

    /**
     * 删除多个keys
     *
     * @param keys 多个键
     * @return 删除成功-1，失败-0
     */
    public static long del(String... keys) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.del(keys);
        jedis.close();
        return data;
    }

    /**
     * 删除多个keys
     *
     * @param keys 多个键
     * @return 删除成功-1，失败-0
     */
    public static long del(byte[]... keys) {
        Jedis jedis = getInstance().getResource();
        long data = jedis.del(keys);
        jedis.close();
        return data;
    }

    /**
     * 返回key所存储的字符串的长度
     *
     * @param key 键
     * @return 字符串的长度，当key不存在返回 0
     */
    public static long strlen(String key) {
        Jedis jedis = getInstance().getResource();
        long len = jedis.strlen(key);
        jedis.close();
        return len;
    }
}
